home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / keyb / stfkey40.zip / STUFF321.ASM < prev    next >
Assembly Source File  |  1992-07-09  |  52KB  |  2,088 lines

  1.    PAGE 80,132
  2.    TITLE "StuffIt, Delayed keyboard stuffer. (C) Terje Mathisen 1989-92"
  3.  
  4. VerNr   EQU 321h
  5. VerStr  EQU '3.21'
  6.  
  7.         LOCALS                  ; Use TASM features for easier development.
  8.         NOJUMPS
  9.  
  10. TicksPrDay      EQU 1573041
  11. TicksPrHour     EQU 65543
  12.  
  13. BIOS SEGMENT AT 40h
  14.         ORG 1Ah
  15. BufferHead      dw ?
  16. BufferTail      dw ?
  17. BufferStart     dw 16 dup (?)
  18. BufferEnd       LABEL word
  19.  
  20.         ORG 49h
  21. VideoMode       db ?
  22. CrtWidth        dw ?
  23.  
  24.         ORG 4Eh
  25. CurrStart       dw ?
  26. Cursor          dw ?
  27.  
  28.         ORG 6Ch
  29. BIOS_Timer      dw 2 dup (?)
  30.  
  31.         ORG 80h
  32. KbdBufferStart  dw ?
  33. KbdBufferEnd    dw ?
  34.  
  35. BIOS ENDS
  36.  
  37. BOOT SEGMENT AT 0F000h
  38.         ORG 0FFF0h
  39. RebootLocation  LABEL FAR
  40. BOOT ENDS
  41.  
  42. ; To reduce the resident size of StuffIt, the script is compressed into tokens
  43. ; using the following algorithm:
  44. ;
  45. ; 0 and 224 are used as the character part of function keys. These codes are
  46. ; always followed by a the function key scan code.
  47. ;
  48. ; 254 is an escape character, followed by a char:scan pair. This is also used
  49. ; if we need to enter Chr(254) or Chr(255)
  50. ;
  51. ; 255 is the lead-in for an extended function code. It will be followed by
  52. ; one of these codes:
  53. ;
  54. ; Codes for extended functions, i.e not normal keys:
  55.  
  56. REBOOT_CODE     = 0
  57. ATTIME_CODE     = 1
  58. DELTATIME_CODE  = 2
  59. FIND_CODE       = 3
  60. PROMPT_CODE     = 4
  61. PRTSCRN_CODE    = 5
  62. BREAK_CODE      = 6
  63.  
  64. ; Use 255 to signal that the following is an extended function
  65.  
  66. EXTENDED_CODE   = 255
  67.  
  68. ; Use 254 as lead-in for keys that need both char & scan.
  69.  
  70. GETWORD_CODE    = 254
  71.  
  72. ; All other codes (1-221,223-253) are presumed to be single characters to
  73. ; place in the kbd buffer. All of them will receive the same scan code (2).
  74. ; If your application cannot accept this, you must use the {c} or [c] syntax,
  75. ; where <c> is any character. This will be translated to the US std enh kbd
  76. ; char:scan pair.
  77.  
  78.  
  79. CODE SEGMENT PARA PUBLIC 'code'
  80.         ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  81.         ORG 0
  82. PspStart label byte
  83.  
  84.         ORG 5Ch
  85. ResidentSize    dw ?
  86.  
  87. LowStart label byte                     ; Small size TSR
  88.  
  89.         ORG 80h
  90. CommandLen      db ?
  91. CommandLine     LABEL BYTE
  92.  
  93.         ORG 100h
  94. start:
  95.         jmp init
  96.  
  97. Semafor equ 'ST'                        ; Stuffit
  98.  
  99. ;LowStart label byte                     ; Move this label to decrease size!
  100. HighStart label byte
  101.  
  102. MoveDown EQU HighStart - LowStart       ; Relocation factor for resident
  103.                                         ; part of StuffIt
  104.  
  105. Int2F   proc far
  106.         cmp ax,0E000h
  107.          je @@maybe
  108.  
  109. @@chain:
  110. ;       jmp [OldInt2F]
  111.         db 0EAh
  112. OldInt2F dd ?
  113.  
  114. @@maybe:
  115.         cmp dx,Semafor                  ; Be safe, insist on semafor in DX
  116.  
  117. current = $
  118.         org $-2
  119. Semafor_1 label word
  120.         org current
  121.  
  122.          jne @@chain
  123.  
  124. @@We_Are_Here:
  125.         mov al,0FFh
  126.         mov dx,cs
  127.         mov bx,VerNr
  128.  
  129.         iret
  130.  
  131. Int2F   endp
  132.  
  133.  
  134. ; Here comes the actual, INT 8, code, which will run on every timer tick to
  135. ; execute the tokenized script.
  136. ;
  137. ; To reduce the performance overhead of having StuffIt loaded, I use a dirty
  138. ; trick: Self-modifying code.
  139. ;
  140. ; When the script has finished, the total overhead is reduced to just
  141. ; 3 instructions: PUSHF / CALL (FAR IMMEDIATE) OldTimer / IRET
  142.  
  143. PUSH_AX_OPCODE EQU  50h                 ; Opcode for PUSH AX, used when active
  144. IRET_OPCODE    EQU 0CFh                 ; Opcode for IRET, used when disabled
  145.  
  146. MyTimer PROC FAR
  147.         pushf
  148. ;       call [OldTimer]                 ; Call the old timer code first, to
  149.         db 09Ah                         ; do it's stuff and re-enable the HW.
  150. OldTimer dw ?,?
  151.  
  152. SelfModify label byte                   ; This will be IRET when idle
  153.         push ax                         ; PUSH AX = 50h, IRET = 0CFh
  154.  
  155. ; The [active] flag is initialized to -1. This way I can use an INC
  156. ; instruction to detect the first entry into this code. Multiple
  157. ; invocations will jump directly to the exit code, with very little
  158. ; overhead. (A total of only 7 instructions and 1 short jump.)
  159.  
  160.         inc byte ptr [cs:active-MoveDown] ;  INC from -1 to 0
  161.          jnz Already_Active
  162.  
  163.         STI
  164.         CLD
  165.  
  166.         push bx
  167.         push cx
  168.  
  169.         push dx
  170.         push si
  171.         push di
  172.         push ds
  173.         push es
  174.  
  175.         push cs
  176.         pop ds
  177.         ASSUME DS:CODE
  178.  
  179.         mov es,[BiosSeg-MoveDown]       ; I store 40h in a memory variable and
  180.                                         ; load ES from it, as this saves one
  181.                                         ; instruction vs MOV AX,40/MOV ES,AX
  182.         ASSUME ES:BIOS
  183.  
  184.         call word ptr [StuffMode-MoveDown] ; State machine, call the current
  185.                                         ; state handler.
  186.  
  187.         pop es
  188.         pop ds
  189.         pop di
  190.         pop si
  191.         pop dx
  192.  
  193.         pop cx
  194.         pop bx
  195.  
  196.         ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  197.  
  198.         CLI
  199.  
  200. Already_Active:
  201.  
  202.         dec byte ptr [cs:active-MoveDown]
  203.  
  204.         pop ax
  205.         iret
  206. MyTimer ENDP
  207.  
  208.         ASSUME CS:CODE,DS:CODE,ES:BIOS
  209.  
  210. StuffFinished:
  211.         mov [SelfModify-MoveDown],IRET_OPCODE   ; Disable by self-modifying
  212.                                         ; May be re-enabled by a later
  213.                                         ; invocation of StuffIt.
  214.         ret
  215.  
  216. NextKey proc near
  217.         mov si,[StuffPtr-MoveDown]
  218. GetNext:
  219.         cmp si,[StuffEnd-MoveDown]
  220.          jae StuffFinished
  221.  
  222.         lodsb
  223.         cmp al,GETWORD_CODE
  224.          ja Extended                    ; Extended function
  225.          je @@GetBoth                   ; 254 => char, scan follows
  226.  
  227.         mov ah,2                        ; Simulate scan = 2 for normal chars
  228.         cmp al,224                      ; Character for Enh.Kbd new keys
  229.          je @@GetScan
  230.  
  231.         or al,al
  232.          jne stuff
  233.  
  234. @@GetScan:
  235.         mov ah,[si]
  236.         inc si
  237.          jmp short stuff
  238.  
  239. @@GetBoth:
  240.         lodsw
  241. Stuff:
  242.         CLI
  243.         mov di,[BufferTail]
  244.         stos word ptr [BIOS:di]
  245.         cmp di, OFFSET BufferEnd
  246.  
  247. BufferEndAddr label word
  248.  
  249.          jb @@1
  250.         mov di, OFFSET BufferStart
  251. BufferStartAddr label word
  252. @@1:
  253.         cmp di,[BufferHead]
  254.          je @@Overflow
  255.         mov [BufferTail],di
  256.         STI
  257. StuffOK:
  258.         mov [StuffPtr-MoveDown],si
  259.          jmp GetNext
  260.  
  261. @@OverFlow:
  262.         STI
  263.         ret
  264. NextKey ENDP
  265.  
  266. ExtendedTable label word
  267.   dw Reboot      - MoveDown
  268.   dw AbsTime     - MoveDown
  269.   dw DeltaTime   - MoveDown
  270.   dw StartFind   - MoveDown
  271.   dw StartPrompt - MoveDown
  272.   dw PrtScrn     - MoveDown
  273.   dw CtrlBreak   - MoveDown
  274.  
  275. NrOfCodes = ($ - offset ExtendedTable) SHR 1
  276.  
  277. Extended PROC near
  278.         lodsb                           ; Get function code!
  279.         cmp al,NrOfCodes
  280.          jae StuffFinished              ; Program Error! Abort the script!
  281.  
  282.         cbw                             ; All codes are <= 127, so CBW is OK!
  283.         mov bx,ax
  284.         shl bx,1
  285.         jmp ExtendedTable[bx - MoveDown] ; Jump to function handler
  286.  
  287. Extended endp
  288.  
  289. Reboot proc near
  290.         mov word ptr [BIOS: 72h],1234h  ; == Warm Boot (CtrlAltDel)
  291.         jmp RebootLocation              ; == F000:FFF0
  292. Reboot endp
  293.  
  294. PrtScrn proc near
  295.         int     5
  296.         jmp     GetNext
  297. PrtScrn endp
  298.  
  299. CtrlBreak proc near
  300.         int     1Bh
  301.         xor     ax,ax
  302.         jmp     Stuff
  303. CtrlBreak endp
  304.  
  305. AbsTime:                                ; Both Abs time & Delta time land here
  306. DeltaTime:                              ; ---- " ----
  307.  
  308. GetTime proc near
  309.  
  310.         cmp al, DELTATIME_CODE
  311.         lodsw                           ; Next 3 bytes is # of ticks
  312.         mov dl,[si]
  313.          jz @@TimeOk                    ; Delta time, so wait # of ticks
  314.  
  315. ; Wait until time equal: Calculate remaining ticks
  316.  
  317.         sub ax,[Bios_Timer]
  318.         sbb dl,BYTE PTR [Bios_Timer+2]
  319.          jae @@TimeOk
  320.  
  321.         add ax,TicksPrDay AND 0FFFFh
  322.         adc dl,TicksPrDay Shr 16
  323.  
  324. @@TimeOK:
  325.         inc si
  326.         mov [StuffPtr-MoveDown],si               ; Point